﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using EzyThirdLogic.ExtensionMethods;

namespace EzyThirdLogic
{
    public class TDRemover
    {
        private string[][] fdSet;
        private string tdVar = "";

        public TDRemover()
        {
        }

        public TDRemover(string[][] input)
        {
            fdSet = input;
        }

        public string[][] GetList ()
        {
            return fdSet;
        }
        public string[][] PlotTransitivityStep5()
        {
            string[][] checker = new string[fdSet.Length][];
            for (int i = 0; i < checker.Length; i++)
            {
                checker[i] = new string[fdSet.Length];
            }

            for (int i = 0; i < fdSet.Length; i++)
            {
                int x = -1, y = -1;
                string x1 = "", y1 = "";
                for (int j = 0; j < fdSet.Length; j++)
                {
                    if (fdSet[i][0].Equals(fdSet[j][0]) && x == -1)
                    {
                        x = j;
                        x1 = fdSet[j][0];
                    }
                    if (fdSet[i][1].Equals(fdSet[j][1]) && y == -1)
                    {
                        y = j;
                        y1 = fdSet[j][1];
                    }
                    if (x != -1 && y != -1)
                    {
                        break;
                    }
                }
                checker[x][y] = x1 + "->" + y1;
            }

            return checker;
        }

        public string[][] IdentifyTransitivityStep5(string[][] input, string[][] setJ)
        {
            for (int i = 0; i < input.Length; i++)
            {
                for (int j = 0; j < input.Length; j++)
                {
                    bool flag = false;
                    if (input[i][j] != null)
                    {
                        flag = CheckTransitivityStep5(input, i, j);
                    }
                    if (flag == true)
                    {
                        fdSet = EliminateTransitivityStep5(input, setJ, i, j);
                    }
                }
            }

            return fdSet;
        }

        public bool CheckTransitivityStep5(string[][] input, int x, int y)
        {
            //Aim: Boolean return for transitivity check
            for (int i = 0; i < input.Length; i++)
            {
                String[] st;
                String LHS = ".", RHS = ".";
                if (input[x][i] != null)
                {
                    st = Regex.Split(input[x][i], "->");
                    RHS = st[1];
                    for (int j = 0; j < input.Length; j++)
                    {
                        if (input[j][y] != null)
                        {
                            st = Regex.Split(input[j][y], "->");
                            LHS = st[0];
                        }
                        if (LHS.Equals(RHS) || RHS.IndexOf(LHS) != -1)
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        public string[][] EliminateTransitivityStep5(string[][] input, string[][] jSet, int x, int y)
        {
            //Trim the FDset to remove transitivity FD
            String[] temp = Regex.Split(input[x][y], "->");
            String[][] newFDSet = new String[fdSet.Length - 1][];
            for (int i = 0; i < newFDSet.Length; i++)
            {
                newFDSet[i] = new String[fdSet.Length - 1];
            }
            String LHS = temp[0], RHS = temp[1];
            for (int i = 0; i < jSet.Length; i++)
            {
                if (LHS.Equals(jSet[i][0]) && RHS.Equals(jSet[i][1]))
                {
                    return fdSet;
                }
            }

            int cnt = 0;
            for (int i = 0; i < fdSet.Length; i++)
            {
                if (!fdSet[i][0].Equals(LHS) || !fdSet[i][1].Equals(RHS))
                {
                    newFDSet[cnt][0] = fdSet[i][0];
                    newFDSet[cnt][1] = fdSet[i][1];
                    cnt++;
                }
            }
            tdVar += "Eliminate Transitive FD : " + input[x][y] + "\n";
            return newFDSet;
        }

        public string GetTDVarStep5()
        {
            return tdVar;
        }

        public string ToStringStep5()
        {
            var f = new FunctionalDependencySet(fdSet, fdSet.Length);
            var p = new Partitioner();
            var bigset = p.Partition(f);
            var m = new Merger();
            bigset = m.Merge(bigset, f);
            return bigset.ToString();
        }
    }
}
